package cn.raven.org.service.impl;

import cn.raven.basic.constant.BaseConstant;
import cn.raven.basic.exception.BusinessException;
import cn.raven.basic.service.impl.BaseServiceImpl;
import cn.raven.basic.utils.BaiduAuditUtils;
import cn.raven.basic.utils.EmailUtils;
import cn.raven.basic.utils.StrUtils;
import cn.raven.org.domain.Employee;
import cn.raven.org.domain.Shop;
import cn.raven.org.domain.ShopAuditLog;
import cn.raven.org.mapper.EmployeeMapper;
import cn.raven.org.mapper.ShopAuditLogMapper;
import cn.raven.org.mapper.ShopMapper;
import cn.raven.org.service.IEmployeeService;
import cn.raven.org.service.IShopService;
import cn.raven.org.vo.ShopVo;
import cn.raven.user.domain.Logininfo;
import cn.raven.user.domain.User;
import com.alibaba.fastjson.JSON;
import jdk.nashorn.internal.parser.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**

* @Description: 部门管理业务层
* @Author: king
* @Version: 1.0
* @Date:  2022/6/21 17:515
  */
@Service
//只读事务
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private ShopAuditLogMapper shopAuditLogMapper;
    @Autowired
    private IEmployeeService employeeService;
    @Autowired
    private RedisTemplate redisTemplate;


    /** 
    * @Title: settlement
    * @Description: 店铺入职信息验证
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/2 18:00  
    * @Parameters: [shop]
    * @Return void
      */
    @Override
    @Transactional
    public void settlement(Shop shop) throws IOException {
        Employee admin = shop.getAdmin();
        //校验店铺信息是否违规
        if (!BaiduAuditUtils.TextCensor(shop.getName()) ||
                !BaiduAuditUtils.TextCensor(shop.getTel()) ||
                !BaiduAuditUtils.TextCensor(shop.getAddress())){
            throw new BusinessException("信息已违规,请重新填写");
        }
        //校验图片是否违规
        String str = BaseConstant.FastDfsConstant.FASTDFS_PREFIX+shop.getLogo();
        if (!BaiduAuditUtils.ImgCensor(str)){
            throw new BusinessException("图片不合规,请重新选择");
        }


        //校验参数
        if(StringUtils.isEmpty(shop)){
            throw new BusinessException("店铺入驻信息必须填写");
        }
        //两次密码是否一致
        if(!admin.getPassword().equals(admin.getComfirmPassword())){
            throw new BusinessException("两次密码不一致");
        }
        //判断店铺是否存在
        Shop shopName = shopMapper.findByName(shop.getName());
        if (shopName != null){
            throw new BusinessException("店铺已注册，请重新填写");
        }
        //判断管理员是否存在
        Employee employee = employeeMapper.findByUsername(admin.getUsername());
        if(employee !=null && employee.getId() == shopName.getAdminId()){
            throw new BusinessException("管理员已存在，并且以绑定店铺");
        }
        //手机号是否注册
        employee = employeeMapper.findByPhone(admin.getPhone());
        if (employee != null){
            throw new BusinessException("手机号已被注册,请直接登录");
        }
        //根据业务键和电话号创客key
        String phoneCodeKey = BaseConstant.BusinessConstant.SMS_SHOP_REGISTER_CODE + admin.getPhone();
        Object phoneCodeValue = redisTemplate.opsForValue().get(phoneCodeKey);
        if (phoneCodeValue == null){
            throw new BusinessException("验证码已过期,请重新获取");
        }
        //通过：分隔获取redis中的code，来和用户填写的验证码比较
        String phoneCode = phoneCodeValue.toString().split(":")[1];
        if (!phoneCode.equalsIgnoreCase(admin.getPhoneCode())){
            throw new BusinessException("验证码错误,请输入正确的验证码");
        }

        if (employee == null){
            // 保存admin，返回了主键Id
            employeeService.add(admin);
            employee = admin;
        }
        //根据emp返回的自增主键赋值给shop外键
        shop.setAdminId(employee.getId());
        //保存店铺信息，此次情况，随便先保存谁都可以
        shopMapper.add(shop);
        //根据shop返回的自增id来保存emp的外键
        employee.setShopId(shop.getId());
        employeeService.update(employee);
    }
    
    /** 
    * @Title: pass
    * @Description: 店铺入驻审核通过
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/2 18:01  
    * @Parameters: [shopAuditLog]
    * @Return void
      */
    public void pass(ShopAuditLog shopAuditLog, HttpServletRequest request) {
        //修改店铺状态为通过
        Long id = Long.valueOf(shopAuditLog.getShopId());
        Shop shop = shopMapper.findOne(id);
        shop.setState(2);
        shopMapper.update(shop);
        String token = request.getHeader("token");
        Logininfo logininfo = (Logininfo) redisTemplate.opsForValue().get(token);
        //操作人
        shopAuditLog.setAuditId(logininfo.getId());
        //保存日志信息
        shopAuditLogMapper.add(shopAuditLog);
        Employee emp = employeeMapper.findOne(shop.getAdminId());
        String subject = "宠物乐园店铺入驻结果通知";
        String url = "http://localhost:8080/shop/live/"+shopAuditLog.getShopId();
        String text = "<h1>你的店铺入驻申请已审核通过,点击下方链接激活</h1>"+"<a href="+url+">"+url+"</a>";
        EmailUtils.sendMail(subject,text,emp.getEmail(),null,true);

    }
    /** 
    * @Title: reject
    * @Description: 店铺入驻审核驳回
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/2 18:01  
    * @Parameters: [shopAuditLog]
    * @Return void
      */
    @Override
    public void reject(ShopAuditLog shopAuditLog,HttpServletRequest request) {
        //修改店铺状态为通过
        Long id = Long.valueOf(shopAuditLog.getShopId());
        Shop shop = shopMapper.findOne(id);
        shop.setState(-1);
        shopMapper.update(shop);
        String token = request.getHeader("token");
        Logininfo logininfo = (Logininfo) redisTemplate.opsForValue().get(token);
        //操作人
        shopAuditLog.setAuditId(logininfo.getId());
        //保存日志信息
        shopAuditLogMapper.add(shopAuditLog);
        //发送激活邮件给用户
        Employee emp = employeeMapper.findOne(shop.getAdminId());
        String subject = "宠物乐园店铺入驻结果通知";
        String url = "http://localhost:8081/#/RegisterUpdate?shopId="+shopAuditLog.getShopId();
        String text = "<h1>你的店铺入驻申请未审核通过,点击下方链接修改店铺信息</h1>"+"<a href="+url+">"+url+"</a>";
        EmailUtils.sendMail(subject,text,emp.getEmail(),null,true);
    }

    /**
    * @Title: not
    * @Description: 店铺入职审核拒接
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/3 20:26
    * @Parameters: [shopAuditLog]
    * @Return void
      */
    @Override
    public void not(ShopAuditLog shopAuditLog,HttpServletRequest request) {
        //修改店铺状态为通过
        Long id = Long.valueOf(shopAuditLog.getShopId());
        Shop shop = shopMapper.findOne(id);
        shop.setState(-2);
        shopMapper.update(shop);
        String token = request.getHeader("token");
        Logininfo logininfo = (Logininfo) redisTemplate.opsForValue().get(token);
        //操作人
        shopAuditLog.setAuditId(logininfo.getId());
        //保存日志信息
        shopAuditLogMapper.add(shopAuditLog);
        //发送激活邮件给用户
        Employee emp = employeeMapper.findOne(shop.getAdminId());
        ShopAuditLog shopLog =  shopAuditLogMapper.findShop(shop.getId());
        String note = shopLog.getNote();
        String subject = "宠物乐园店铺入驻结果通知";
        String text = "<h1>你丫店铺入驻申请已拒绝,拒绝原因： "+note+"</h1>";
        EmailUtils.sendMail(subject,text,emp.getEmail(),null,true);
    }

    /**
    * @Title: live
    * @Description: 点击激活后直接修改状态为已审核
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/2 20:51  
    * @Parameters: [id]
    * @Return void
      */
    @Override
    public void live(Integer id) {
        Shop shop = shopMapper.findOne(Long.valueOf(id));
        shop.setState(1);
        shopMapper.update(shop);
    }

    /**
    * @Title: batchAdd
    * @Description: 导入批量新增
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/3 20:26
    * @Parameters: [shops]
    * @Return void
      */
    @Override
    public void batchAdd(List<Shop> shops) {
        shopMapper.batchAdd(shops);
    }

    /**
    * @Title: echarts
    * @Description: 首页柱状图
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/3 20:26
    * @Parameters: [shopVo]
    * @Return java.util.Map<java.lang.String,java.lang.Object>
      */
    @Override
    public Map<String, Object> echarts(ShopVo shopVo) {
        List<ShopVo> shopVos = shopMapper.findEcharts(shopVo);
        List<Integer> states = shopVos.stream().map(ShopVo::getState).collect(Collectors.toList());
        List<Integer> counts = shopVos.stream().map(ShopVo::getCount).collect(Collectors.toList());
        List<Object> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        for (ShopVo shop: shopVos) {
            if (shop.getState()==-1) {
                list.add("驳回");
            } else if (shop.getState()==0) {
                list.add("待审核");
            } else if (shop.getState()==1) {
                list.add("审核通过");
            } else if (shop.getState()==2) {
                list.add("待激活");
            }else if (shop.getState()== -2) {
                list.add("拒绝");
            }
        }

        map.put("x",list);
        map.put("y",counts);
        return map;
    }

    @Override
    public void smsCode(Shop shop) {
        Employee admin = shop.getAdmin();
        String phone = admin.getPhone();
        //校验店铺信息是否违规
        if (!BaiduAuditUtils.TextCensor(shop.getName()) ||
                !BaiduAuditUtils.TextCensor(shop.getTel()) ||
                !BaiduAuditUtils.TextCensor(shop.getAddress())){
            throw new BusinessException("信息已违规,请重新填写");
        }
        //校验图片是否违规
        String str = "http://123.207.27.208"+shop.getLogo();
        if (!BaiduAuditUtils.ImgCensor(str)){
            throw new BusinessException("图片不合规,请重新选择");
        }
        //校验参数
        if(StringUtils.isEmpty(shop.getName())||
                !BaiduAuditUtils.TextCensor(shop.getTel()) ||
                !BaiduAuditUtils.TextCensor(shop.getAddress())){
            throw new BusinessException("店铺入驻信息必须填写");
        }
        //判断店铺是否存在
        Shop shopName = shopMapper.findByName(shop.getName());
        if (shopName != null){
            throw new BusinessException("店铺已注册，请重新填写");
        }
        //判断管理员是否存在
        Employee employee = employeeMapper.findByUsername(admin.getUsername());
        if(employee !=null && employee.getId() == shopName.getAdminId()){
            throw new BusinessException("管理员已存在，并且以绑定店铺");
        }
        //手机号是否注册
        employee = employeeMapper.findByPhone(admin.getPhone());
        if (employee != null){
            throw new BusinessException("手机号已被注册,请直接登录");
        }
        //业务键+电话号生成Redis中的key
        String smsCodeKey = BaseConstant.BusinessConstant.SMS_SHOP_REGISTER_CODE + phone;
        //获取redis中对应的验证码
        Object smsCodeValue = redisTemplate.opsForValue().get(smsCodeKey);
        //保存验证码
        String phoneCode = "";
        //如果redis没有验证码
        if (smsCodeValue ==null){//生成验证码
            phoneCode = StrUtils.getComplexRandomString(4);

        }else {//如果有
            String[] smsSplit = smsCodeValue.toString().split(":");
            Long oldTime = Long.valueOf(smsSplit[0]);
            Long nowTime = System.currentTimeMillis();
            //当前时间戳减去存在验证码的时间戳，小于一分钟
            if (nowTime - oldTime < 1*60*1000){
                throw new BusinessException("请一分钟后点击获取");
            }
            //直接使用当前验证码
            phoneCode = smsSplit[1];
        }
        String phoneCodeReal = System.currentTimeMillis()+":"+phoneCode;
        //将验证码保存到redis
        redisTemplate.opsForValue().set(smsCodeKey,phoneCodeReal,3, TimeUnit.MINUTES);
        //发短信
        System.out.println("你丫的验证码是："+ phoneCode);

    }
}
